home *** CD-ROM | disk | FTP | other *** search
- {$N+,E+,G+,X+}
- PROGRAM ApfelVESA;
- {
- (c) by Mark Stehr mkstehr@cip.informatik.uni-erlangen.de
- }
- Uses
- VGraph,Crt,Dos,Printer;
-
- CONST
- modus = V640x480x256;
- MaximaleTiefe = 255;
-
- Bild : BOOLEAN = FALSE;
- message : STRING[35] = 'Bitte drücken Sie eine Taste ...';
-
- TYPE
- {$ifopt N-}
- Typ = Real;
- {$else}
- Typ = Extended;
- {$endif}
-
- MandelType = RECORD
- MaxTiefe : WORD;
- rlr, { Left Side }
- rrr, { Right }
- ior, { Up }
- iur { Down }
- : REAL;
- hh,mm,ss : WORD;
- END;
-
- MandelBrotHook = FUNCTION(r,i :Typ):WORD;
- AlgorithmusHook = PROCEDURE(dx,dy : TYP);
-
- VAR
- Mandel : MandelType;
- FileName : STRING;
- taste : CHAR;
- hh2,mm2,ss2,sek100 : WORD;
- hh1,mm1,ss1 : WORD;
- mandelbrot : MandelBrotHook;
- algorithmus : AlgorithmusHook;
- i : WORD;
- puffer : POINTER;
- pal : PaletteType;
- MaxColor : LONGINT;
- MaxX,MaxY : INTEGER;
-
- PROCEDURE apfelmann; FORWARD;
-
- {$F+}
- FUNCTION mandelbrot86(r,i :Typ):WORD;
- CONST
- abbruchwert = 4;
- MaxTiefe = MaximaleTiefe;
- VAR
- x,y,x2,y2,xx : Typ;
- tiefe : WORD;
- BEGIN
- x := 0;
- y := 0;
- Tiefe:=0;
-
- REPEAT
- x2 := x*x;
- y2 := y*y;
- xx := x2 - y2 + r;
- y := 2*x*y+ i;
- x := xx;
- Inc(Tiefe);
- UNTIL ((x2+y2)>abbruchwert) OR (Tiefe>=MaxTiefe);
-
- mandelbrot86:=Tiefe;
- END;
-
- FUNCTION mandelbrot87(r,i :Typ):WORD;
- {
- Verwendung der Register:
- ax = Funktionswert: Anzahl der Iterationen
- bx = Abbruchwert
- cx = Max. Anzahl der Iterationen
- }
- LABEL
- fertig;
- CONST
- abbruchwert : WORD = 4; { Wegen FICOMP }
- MaxTiefe : WORD = MaximaleTiefe;
- {$ifopt G-}
- VAR
- status : WORD;
- {$endif}
- BEGIN
- asm
-
- finit { Alles neu }
- fld tbyte ptr [r] { Lade r }
- fld tbyte ptr [i] { Lade i }
- fldz { x^2 = 0 }
- fldz { y^2 = 0 }
- fldz { a = 0 }
- fldz { b = 0 }
-
- mov cx,[MaxTiefe] { cx = Max. Anzahl der Iterationen }
- mov bx,[abbruchwert] { bx = Abbruchwert }
- mov dx,0 { ax = Funktioneswert = 0 }
-
- @repeat:
-
- fld st(1) { Kopiere x }
- fmul st(0),st(0) { x^2 }
- fst st(4) { Speicher x^2 }
-
- fld st(1) { Kopiere y }
- fmul st(0),st(0) { y^2 }
- fst st(4) { Speicher y^2 }
- fsub { x^2 - y^2 }
-
- fadd st(0),st(6) { x(n+1) = x^2 - x^2 + r }
- fxch st(2) { Austausch x <> x(n+1) }
-
- fmul { x * y }
- fadd st(0),st(0) { 2 * x * y }
- fadd st(0),st(4) { y(n+1) = 2*x*y+i }
-
- inc dx { Inc Tiefe }
-
- fld st(3) { Kopier x^2 }
- fadd st(0),st(3) { und addier y^2 }
-
- ficomp [abbruchwert] { Vergleiche }
- {$ifopt G+}
- fstsw ax
- {$else}
- fstsw [status]
- mov ax,[status] { Speicher die Copro-Flags in AX }
- {$endif}
- sahf { mov flags,ax }
- ja fertig { Ja, fertig }
-
- loop @repeat { cx = cx -1 > 0 ? }
-
- fertig:
-
- finit
- mov @result,dx { Ergebnis nicht vergessen }
- END;
- END;
- {$F-}
-
-
- PROCEDURE RestoreArea;
- CONST
- VRam : POINTER = Ptr($a000,0);
- BEGIN
- SetActivePage(0);
- Move(puffer^,VRam^,$ffff);
- END;
-
- PROCEDURE SaveArea;
- CONST
- VRam : POINTER = Ptr($a000,0);
- BEGIN
- SetActivePage(0);
- Move(VRam^,puffer^,$ffff);
- END;
-
- PROCEDURE achsenkreuz;
- VAR
- i : WORD;
- BEGIN
- SetColor(MaxColor DIV 2);
- Rectangle(0,0,MaxX,MaxY);
- WITH mandel DO BEGIN
- i:=ROUND(ior/((ior-iur)/(MaxY+1)));
- line(0,i,MaxX,i);
- i:=MaxX-ROUND(rrr/((rrr-rlr)/(MaxX+1)));
- line(i,0,i,MaxY);
- END;
- END;
-
- PROCEDURE ansehen;
- BEGIN
- SetGraphMode(GetGraphMode);
- SetPal(pal);
- RestoreArea;
- ReadKey;
- RestoreCrtMode;
- END;
-
-
- PROCEDURE zoom;
- VAR
- x1,y1,x2,y2,hoehe,breite: WORD;
- dx,dy : TYP;
- faktor : TYP;
- BEGIN
- SetGraphMode(GetGraphMode);
- SetPal(pal);
- RestoreArea;
- SetWriteMode(XorPut);
-
- faktor := (MaxX+1) / (MaxY+1);
- hoehe := MaxY DIV 4;
- breite := Round(hoehe*faktor);
- x1 := breite DIV 2;
- y1 := hoehe DIV 2;
- x2 := x1 + breite;
- y2 := y1 + hoehe;
- SetColor(MaxColor DIV 2);
- REPEAT
- breite := Round(hoehe*faktor);
- x2 := x1 + breite;
- y2 := y1 + hoehe;
- Rectangle(x1,y1,x2,y2);
- taste := ReadKey;
- Rectangle(x1,y1,x2,y2);
- CASE taste OF
- #27 : BEGIN
- SetWriteMode(CopyPut);
- RestoreCrtMode;
- Exit;
- END;
- #77 : IF x2 < MaxX THEN
- Inc(x1); { Right }
- #75 : IF x1 > 0 THEN
- Dec(x1); { Left }
- #72 : IF y1 > 0 THEN
- Dec(y1); { Up }
- #80 : IF y2 < MaxY THEN
- Inc(y1); { Down }
- '+' : BEGIN
- IF hoehe <= MaxY THEN BEGIN
- Inc(hoehe);
- END;
- END;
- '-' : BEGIN
- IF hoehe > 0 THEN BEGIN
- Dec(hoehe);
- END;
- END;
- END;
- UNTIL taste = #13;
-
- WITH Mandel DO BEGIN
- dx:=(rrr-rlr)/(MaxX+1);
- dy:=(ior-iur)/(MaxY+1);
- rlr := rlr + (x1*dx);
- rrr := rrr - (MaxX-x2)*dx;
- ior := ior - (y1*dy);
- iur := iur + (MaxY-y2)*dy;
- END;
- SetWriteMode(NormalPut);
- RestoreCrtMode;
- apfelmann;
- END;
-
- PROCEDURE effekt;
- VAR
- OldPal : PaletteType;
- NewPal : PaletteType;
- BEGIN
- SetGraphMode(GetGraphMode);
- SetPal(pal);
- RestoreArea;
- GetPal(OldPal);
- NewPal := OldPal;
- REPEAT
- PushPal(NewPal);
- UNTIL KeyPressed;
- ReadKey;
- SetPal(OldPal);
- RestoreCrtMode;
- END;
-
-
- PROCEDURE eingabe;
- BEGIN
- WITH Mandel DO BEGIN
- Crt.Window(43,14,77,22);
- TextBackGround(1);
- ClrScr;
- TextColor(LightCyan);
- GotoXY(1,2);
- WriteLN(' Bitte geben Sie die Werte ein.');
- REPEAT
- GotoXY(3,4);
- Write('Max.Tiefe: ');
- READLN(MaxTiefe);
- UNTIL (MaxTiefe>0) AND (MaxTiefe<256);
- REPEAT
- GotoXY(3,5);
- Write('Rlr : ');
- READLN(rlr);
- UNTIL (rlr>-3) AND (rlr<2.9);;
- REPEAT
- GotoXY(3,6);
- Write('Rrr : ');
- READLN(rrr);
- UNTIL (rrr>rlr) AND (rrr<3);
- REPEAT
- GotoXY(3,7);
- Write('Ior : ');
- READLN(ior);
- UNTIL (ior>-2) AND (ior<2);
- REPEAT
- GotoXY(3,8);
- Write('Iur : ');
- READLN(iur);
- UNTIL (iur<ior) AND (iur<2);
- END;
- END;
-
-
- PROCEDURE init_text;
- BEGIN
- TextMode(Co80);
- TextBackGround(Black);
- TextColor(LightGray);
- END;
-
-
- PROCEDURE hardcopy_char(dichte:INTEGER);
-
- FUNCTION potenz(zeile:INTEGER):INTEGER;
- BEGIN
- CASE zeile OF
- 1:Potenz:=128;
- 2:Potenz:=64;
- 3:Potenz:=32;
- 4:Potenz:=16;
- 5:Potenz:=8;
- 6:Potenz:=4;
- 7:Potenz:=2;
- 8:Potenz:=1;
- END;
- END;
-
- VAR
- spalte,zeile,pixel :INTEGER;
- farbe1,farbe2,print :INTEGER;
- grafik :STRING[5];
- an_zeilen,an_buch,zaehler:INTEGER;
- i,j : WORD;
- BEGIN
- SetGraphMode(GetGraphMode);
- SetPal(pal);
- RestoreArea;
- CASE dichte OF
- 0:Pixel:=2;
- 1:Pixel:=2;
- 2:Pixel:=2;
- 3:Pixel:=1;
- END;
- an_zeilen:=((MaxY+1) DIV 11)*11;
- an_buch:=(((MaxY+1) DIV 11)*Pixel)+32;
- grafik:=Chr(27)+'&'+Chr(0)+Chr(33)+Chr(an_buch); {Benutzer def. Zeichen}
- Write(LST,Chr(7)); {Druckersignal}
- Write(LST,Chr(27),Chr(64)); {Drucker init.}
- Write(LST,Chr(27),'A',Chr(8),Chr(27),'2'); {Zeilenabstand 8/72}
- Write(LST,Chr(27),':',Chr(0),Chr(0),Chr(0)); {Kopieren ins Download}
- Write(LST,Chr(27),'%1',Chr(0)); {Benutzer def. Zeichensatz}
- Write(LST,#27,'U',#1); {Unidirekt.}
- IF Pixel=1 THEN Write(LST,#27,'P')
- ELSE Write(LST,#27,'M');
- spalte:=MaxX;
- REPEAT
- zaehler:=0;
- Write(LST,Grafik);
- FOR zeile:=0 TO (an_zeilen)-1 DO BEGIN
- print:=0;
- FOR j:=spalte DOWNTO (spalte-7) DO BEGIN
- farbe1:=getpixel(j,zeile-1);
- farbe2:=getpixel(j,zeile);
- IF farbe1<>farbe2 THEN print:=print+potenz(spalte-j+1)
- ELSE BEGIN
- farbe1:=getpixel(j+1,zeile);
- farbe2:=getpixel(j,zeile);
- IF farbe1<>farbe2 THEN print:=print+potenz(spalte-j+1);
- END;
- END; {von j}
- FOR i:=1 TO Pixel DO BEGIN
- IF (zaehler MOD 11)=0 THEN Write(LST,#139);
- INC(zaehler,1);
- Write(LST,Chr(print));
- END; {von i}
- END; {von zeile}
- FOR i:=33 TO an_buch DO
- Write(LST,Chr(i));
- Write(LST,#13,#10);
- DEC(spalte,8);
- UNTIL spalte<=0;
- Write(LST,#13,#10,#7,#7,#7);
- END;
-
-
- PROCEDURE laden;
- VAR
- f : FILE;
- BEGIN
- Crt.Window(3,25,77,25);
- TextBackGround(Blue);
- ClrScr;
- TextColor(LightCyan);
- Write(' Filename ?: ');
- READLN(FileName);
-
- SetGraphMode(GetGraphMode);
- SetPal(pal);
-
- LoadPCX(0,0,filename+'.pcx');
-
- {$I-}
- Assign(f,filename+'.dat');
- Reset(f,1);
- BlockRead(f,mandel,SizeOf(mandel));
- Close(f);
- {$I+}
- IF IOResult=0 THEN BEGIN
- SaveArea;
- bild := TRUE;
- END;
-
- RestoreCrtMode;
- END;
-
- PROCEDURE speichern;
- VAR
- f : FILE;
- BEGIN
- Crt.Window(3,25,77,25);
- TextBackGround(Blue);
- ClrScr;
- TextColor(LightCyan);
- Write(' Filename ?: ');
- READLN(FileName);
-
- SetGraphMode(GetGraphMode);
- SetPal(pal);
- RestoreArea;
-
- SavePCX(0,0,MaxX,MaxY,filename+'.pcx');
-
- {$I-}
- Assign(f,FileName+'.dat');
- ReWrite(f,1);
- BlockWrite(f,mandel,SizeOf(mandel));
- Close(f);
- {$I+}
-
- RestoreCrtMode;
- END;
-
-
- PROCEDURE stopuhr(stop : BOOLEAN);
- BEGIN
- IF Not Stop THEN BEGIN
- GetTime(hh1,mm1,ss1,sek100);
- stop:=TRUE;
- END
- ELSE BEGIN
- GetTime(hh2,mm2,ss2,sek100);
- IF ss1>ss2 THEN BEGIN
- mandel.ss:=60-ss1+ss2;
- mm1:=SUCC(mm1);
- END
- ELSE
- mandel.ss:=ss2-ss1;
- IF mm1>mm2 THEN BEGIN
- mandel.mm:=60-mm1+mm2;
- hh1:=SUCC(hh1);
- END
- ELSE
- mandel.mm:=mm2-mm1;
- mandel.hh:=hh2-hh1;
- END;
- END;
-
- {---------------------------------------------------------------------------}
- {$F+}
- PROCEDURE algorithmus1(dx,dy : TYP);
- VAR
- x,y,Tiefe2,Tiefe1 : WORD;
- xc,yc : Typ;
-
- FUNCTION zyklodentest(xc,yc:Typ):INTEGER;
- VAR
- r,s,x,y,x2,y2 :Typ;
- BEGIN
- y2:=yc*yc;
- x2:=xc+1.0;
- IF (xc>-0.75) THEN BEGIN
- r:=xc*xc+y2;
- s:=SQRT(r-0.5*xc+0.0625);
- IF ((16.0*r*s)>(5.0*s-4.0*xc+1.0)) THEN
- Zyklodentest:=mandelbrot(xc,yc)
- ELSE
- Zyklodentest:=Mandel.MaxTiefe;
- END
- ELSE
- IF((x2*x2+y2)>0.0625) THEN
- Zyklodentest:=mandelbrot(xc,yc)
- ELSE
- Zyklodentest:=Mandel.MaxTiefe;
- END;
-
- BEGIN
- WITH mandel DO BEGIN
-
- yc:=ior;
- y:=0;
- REPEAT
-
- xc:=rlr;
- x:=0;
- Tiefe1 := Zyklodentest(xc,yc);
- putpixel(x,y,Tiefe1);
- REPEAT
- xc := xc + dx +dx;
- Inc(x,2);
- Tiefe2:=Zyklodentest(xc,yc);
- putpixel(x,y,Tiefe2);
- IF (Tiefe1<>Tiefe2) THEN
- Tiefe1:=Zyklodentest(xc-dx,yc);
- putpixel(x-1,y,Tiefe1);
- Tiefe1 := Tiefe2;
- UNTIL (x>=MaxX);
-
- xc:=rlr;
- FOR x:=0 TO MaxX DO BEGIN
- Tiefe1:=getpixel(x,y);
- Tiefe2:=getpixel(x,y+2);
- IF (Tiefe1=Tiefe2) THEN
- putpixel(x,y+1,Tiefe1)
- ELSE
- putpixel(x,y+1,Zyklodentest(xc,yc-dy));
- xc:=xc+dx;
- END;
-
- yc:=yc-dy-dy;
- INC(y,2);
- UNTIL (y>=MaxY) OR KeyPressed; { !!! }
- END;
- END;
-
- PROCEDURE algorithmus2(dx,dy : TYP);
-
- Procedure Recurse (X1,Y1,X2,Y2 : WORD);
- Var
- CX,CY : Word;
- c : WORD;
- Label
- DontFillIt;
- Begin
- WITH mandel DO BEGIN
- C := mandelbrot(rlr + X1*dx,ior - Y1*dy);
- If C<> mandelbrot (rlr + X1*dx,ior - Y2*dy) Then
- GoTo DontFillIt;
-
- For CX := X1+1 To X2 Do Begin
- If (C<> mandelbrot(rlr + CX*dx,ior - Y1*dy)) Or (C<> mandelbrot (rlr + CX*dx,ior - Y2*dy)) Then
- GoTo DontFillIt;
- End;
- For CY := Y1 To Y2 Do Begin
- If (C<> mandelbrot(rlr + X1*dx,ior - CY*dy)) Or (C<> mandelbrot (rlr + X2*dx,ior - CY*dy)) Then
- GoTo DontFillIt;
- End;
- SetFillStyle(SolidFill,c);
- FillImage(X1+1,Y1+1, X2-1,Y2-1);
- Exit;
-
- DontFillit:
- If (X2-X1) > (Y2-Y1) Then Begin
- CX := (X2-X1) Div 2 +X1;
- For CY := Y1+1 To Y2-1 Do
- PutPixel (CX,CY, mandelbrot(rlr + CX*dx,ior - CY*dy));
- If (CX-X1>1) Then
- Recurse (X1,Y1,CX,Y2);
- If (X2-CX>1) Then
- Recurse (CX,Y1,X2,Y2);
- End
- Else Begin
- CY := (Y2-Y1) Div 2 +Y1;
- For CX := X1+1 To X2-1 Do
- PutPixel (CX,CY, mandelbrot(rlr + CX*dx,ior - CY*dy));
- If (CY-Y1>1) Then
- Recurse (X1,Y1,X2,CY);
- If (Y2-CY>1) Then
- Recurse (X1,CY,X2,Y2);
- END;
- End;
- End;
-
- Begin
- Recurse (0 ,0,MaxX Div 2+1,MaxY);
- Recurse (MaxX Div 2,0,MaxX ,MaxY);
- End;
- {$F-}
-
- PROCEDURE apfelmann;
- VAR
- dx,dy : TYP;
- BEGIN
- SetGraphMode(GetGraphMode);
- SetPal(pal);
- achsenkreuz;
- WITH Mandel DO BEGIN
- dx:=(rrr-rlr)/(MaxX+1);
- dy:=(ior-iur)/(MaxY+1);
- END;
-
- stopuhr(false);
- algorithmus(dx,dy);
- stopuhr(true);
- Beep;
- SavePCX(0,0,MaxX,MaxY,'dummy.pcx');
- ReadKey;
- SaveArea;
- RestoreCrtMode;
- bild:=TRUE;
- END;
-
- {---------------------------------------------------------------------------}
- PROCEDURE menu;
- VAR
- ende : BOOLEAN;
- BEGIN
- ende:=FALSE;
- REPEAT
- TextBackGround(Black);
- Crt.Window(1,1,80,25);
- ClrScr;
- Crt.Window(45,5,78,12);
- TextBackGround(LightGray);
- ClrScr;
- Crt.Window(43,3,77,11);
- TextBackGround(Blue);
- ClrScr;
- TextColor(LightCyan);
- GotoXY(1,3);
- WriteLN(' Apfelmännchen VESA 3.0');
- WriteLN;
- WriteLN(' (c) by Mark Stehr');
- WriteLN(' 91056 Erlangen');
- WriteLN;
- Crt.Window(45,16,78,23);
- TextBackGround(LightGray);
- ClrScr;
- Crt.Window(43,14,77,22);
- TextBackGround(1);
- ClrScr;
- TextColor(LightCyan);
- GotoXY(1,2);
- WriteLN(' Filename : ',FileName);
- WITH Mandel DO BEGIN
- WriteLN(' Dauer : ',hh:2,':',mm:2,':',ss:2);
- WriteLN(' Max.Tiefe: ',MaxTiefe);
- WriteLN(' Rlr : ',rlr:2:20);
- WriteLN(' Rrr : ',rrr:2:20);
- WriteLN(' Ior : ',ior:2:20);
- WriteLN(' Iur : ',iur:2:20);
- END;
- Crt.Window(3,25,77,25);
- TextBackGround(Blue);
- ClrScr;
- TextColor(LightCyan);
- GotoXY(2,1);
- Write(message);
- Crt.Window(5,5,24,23);
- TextBackGround(LightGray);
- ClrScr;
- Crt.Window(3,3,23,22);
- TextBackGround(Blue);
- TextColor(LightCyan);
- ClrScr;
- GotoXY(2,2);Write('W');
- GotoXY(2,4);Write('B');
- GotoXY(2,6);Write('A');
- GotoXY(2,8);Write('S');
- GotoXY(2,10);Write('L');
- GotoXY(2,12);Write('D');
- GotoXY(2,14);Write('Z');
- GotoXY(2,16);Write('E');
-
- GotoXY(2,18);Write('Esc ');
- TextColor(14);
- GotoXY(4,2);Write('erte eingeben');
- GotoXY(4,4);Write('erechnen');
- GotoXY(4,6);Write('nsehen');
- GotoXY(4,8);Write('peichern');
- GotoXY(4,10);Write('aden');
- GotoXY(4,12);Write('rucken');
- GotoXY(4,14);Write('oom');
- GotoXY(4,16);Write('ffekt');
- GotoXY(6,18);Write('Ende');
- Crt.Window(1,1,80,25);
- REPEAT
- GetTime(hh2,mm2,ss2,sek100);
- GotoXY(66,25);
- IF (hh2<10) THEN Write('0');
- Write(hh2,':');
- IF (mm2<10) THEN Write('0');
- Write(mm2,':');
- IF (ss2<10) THEN Write('0');
- Write(ss2);
- UNTIL KeyPressed;
- taste:=ReadKey;
- CASE UpCase(taste) OF
- 'W':eingabe;
- 'B':apfelmann;
- 'A':IF bild THEN ansehen;
- 'S':IF bild THEN Speichern;
- 'L':laden;
- 'D':IF bild THEN hardcopy_char(1);
- 'Z':IF bild THEN zoom;
- 'E':IF bild THEN effekt;
- #27:ende:=TRUE;
- END;
- UNTIL ende;
- END;
-
- BEGIN
- GetMem(puffer,$FFFF);
-
- IF test8087 <> 0 THEN
- mandelbrot := mandelbrot87
- ELSE
- mandelbrot := mandelbrot86;
-
- Algorithmus := algorithmus1;
-
- InitVesa(modus);
- MaxX := GetMaxX;
- MaxY := GetMaxY;
- MaxColor := GetMaxColor;
- NewPal(pal);
- RestoreCrtMode;
-
- init_text;
- FileName:=#0;
- WITH Mandel DO BEGIN
- hh:=0;
- mm:=0;
- ss:=0;
- rrr:=1.0;
- rlr:=-2.0;
- ior:=1.15;
- iur:=-1.15;
- MaxTiefe:=MaximaleTiefe;
- END;
- menu;
- CloseVesa;
-
- FreeMem(puffer,$FFFF);
- END.